package com.github.icloudpay.pay.core.service.pay;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.icloudpay.pay.core.biz.PayOrderBiz;
import com.github.icloudpay.pay.core.biz.PaySerialBiz;
import com.github.icloudpay.pay.core.entity.PayChannel;
import com.github.icloudpay.pay.core.entity.PayChannelInterface;
import com.github.icloudpay.pay.core.entity.PayOrder;
import com.github.icloudpay.pay.core.entity.PaySerial;
import com.github.icloudpay.pay.core.inter.PayObjectService;
import com.github.icloudpay.pay.core.inter.PaymentHandlerService;
import com.github.icloudpay.pay.core.mapper.PayChannelInterfaceMapper;
import com.github.icloudpay.pay.core.util.SpringContextHolder;
import com.github.wxiaoqi.security.common.admin.pay.request.CreateOrderRequest;
import com.github.wxiaoqi.security.common.admin.pay.request.OnlinePaymentRequest;
import com.github.wxiaoqi.security.common.admin.pay.request.PayOrderRequest;
import com.github.wxiaoqi.security.common.admin.pay.response.CreateOrderResponse;
import com.github.wxiaoqi.security.common.admin.pay.response.PayOrderResponse;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.FlyrayBeanUtils;
import com.github.wxiaoqi.security.common.util.EntityUtils;
import com.github.wxiaoqi.security.common.util.SequenceUtil;


/** 
 * @author: bolei
 * @date：2017年4月30日 上午10:43:54 
 * @description：支付逻辑处理  
 */
@Service("paymentHandlerService")
public class PaymentHandlerServiceImpl implements PaymentHandlerService{

	private static final Logger logger = LoggerFactory.getLogger(PaymentHandlerServiceImpl.class);

	@Autowired
	private PayOrderBiz payOrderBiz;
	@Autowired
	private PaySerialBiz paySerialBiz;
	@Autowired
	private PayRouteService payRouteService;
	@Autowired
	private PayChannelInterfaceMapper payChannelInterfaceMapper;
	@Autowired
	private AmqpTemplate rabbitTemplate;

	/**
	 * 创建支付订单
	 * 1.校验订单是否存在
	 * 2.创建订单
	 */
	public CreateOrderResponse createOrder(CreateOrderRequest request) {
		logger.info("创建支付订单开始。。。。。。。{}",EntityUtils.beanToMap(request));
		CreateOrderResponse createOrderResponse = new CreateOrderResponse();
		PayOrder payOrder = new PayOrder();
		payOrder.setPayOrderNo(request.getPayOrderNo());
		payOrder.setPlatformId(request.getPlatformId());
		//查询订单是否已经存在
		PayOrder selectOne = payOrderBiz.selectOne(payOrder);
		if(null != selectOne){
			createOrderResponse.setSuccess(false);
			createOrderResponse.setCode(ResponseCode.ORDER_EXIST.getCode());
			createOrderResponse.setMsg(ResponseCode.ORDER_EXIST.getMessage());
			return createOrderResponse;
		}
		payOrder.setCustomerId(request.getCustomerId());
		payOrder.setMerchantId(request.getMerchantId());
		payOrder.setOrderAmt(new BigDecimal(request.getOrderAmt()));
		payOrder.setPayAmt(new BigDecimal(request.getPayAmt()));
		payOrder.setBody(request.getBody());
		payOrder.setPayCode(request.getPayCode());
		payOrder.setPayTime(new Date());
		payOrder.setOrderStatus("02");//待支付
		payOrder.setRefundedAmt(BigDecimal.ZERO);
		payOrderBiz.insert(payOrder);
		createOrderResponse.setSuccess(true);
		createOrderResponse.setCode(ResponseCode.OK.getCode());
		createOrderResponse.setMsg(ResponseCode.OK.getMessage());
		createOrderResponse.setPayOrderNo(request.getPayOrderNo());
		return createOrderResponse;
	}
	
	/**
	 * 1、根据支付渠编号道需要返回支付通道对象
	 * 2、根据支付通道对象调用相关支付通道支付
	 * 3、创建支付流水
	 */
	@SuppressWarnings("unchecked")
	public PayOrderResponse pay(PayOrderRequest request) {

		PayOrderResponse response = new PayOrderResponse();
		logger.info("获取支付通道对象 start");
		PayChannel payChannel = payRouteService.getRoute(request.getPayChannelNo(), request.getPayCompanyNo());

		if (payChannel == null) {
			response.setSuccess(false);
			response.setCode(ResponseCode.NO_AVAILABLE_PAYCHANNEL.getCode());
			response.setMsg(ResponseCode.NO_AVAILABLE_PAYCHANNEL.getMessage());
			return response;
		}

		logger.info("获取支付通道对象 end");

		//获取支付订单信息
		String payOrderNo = request.getPayOrderNo();
		String platformId = request.getPlatformId();
		logger.info("支付订单号为 :{}",payOrderNo);
		PayOrder payOrder = new PayOrder();
		payOrder.setPayOrderNo(payOrderNo);
		payOrder.setPlatformId(platformId);
		PayOrder selectPayOrder = payOrderBiz.selectOne(payOrder);

		logger.info("支付请求创建订单 start");
		Map<String, Object> reqMap = null;

		try {
			reqMap = FlyrayBeanUtils.objectToMap(request);
			logger.info("请求参数：{}",reqMap);
		} catch (Exception e) {
			logger.error("请求支付异常：{}",e);
			e.printStackTrace();
		}
		if (selectPayOrder == null) {
			response.setSuccess(false);
			response.setCode(ResponseCode.ORDER_NO_EXIST.getCode());
			response.setMsg(ResponseCode.ORDER_NO_EXIST.getMessage());
			return response;
		}
		
		//更新订单表支付方式
		if("ALIPAY".equals(request.getPayCompanyNo())){
			selectPayOrder.setPayMethod("1");
		}else if("WECHAT".equals(request.getPayCompanyNo())){
			selectPayOrder.setPayMethod("2");
		}
		//计算手续费
//		BigDecimal feeRatio = payChannel.getFeeRatio();
//		if(null != feeRatio){
//			BigDecimal payFee = selectPayOrder.getPayAmt().multiply(feeRatio);
//			selectPayOrder.setPayFee(payFee);
//		}
//		payOrderBiz.updateById(selectPayOrder);
		PaySerial paySerial = new PaySerial();
		//组装支付流水参数
		paySerial.setPayOrderNo(request.getPayOrderNo());
		paySerial.setPlatformId(request.getPlatformId());
		List<PaySerial> paySerialList = paySerialBiz.selectList(paySerial);
		for(PaySerial paySerials:paySerialList){
			//状态为支付中，支付成功，作废的订单不能发起支付
			if("00".equals(paySerials.getPayStatus()) || "03".equals(paySerials.getPayStatus()) || "04".equals(paySerials.getPayStatus())){
				response.setSuccess(false);
				response.setCode(ResponseCode.ORDER_PAID.getCode());
				response.setMsg(ResponseCode.ORDER_PAID.getMessage());
				return response;
			}
		}
		
		paySerial = setPaySerial(request, selectPayOrder);
		paySerialBiz.insert(paySerial);
		logger.info("支付请求写支付流水 end");

		Map<String,Object> retMap = getPayObject(selectPayOrder, payChannel, paySerial, request);
		logger.info("支付请求创建订单---end---{}",retMap);
		if((boolean) retMap.get("success")){
			//扫码接口不更新状态
			if(!"0".equals((String) retMap.get("scanCode"))){
				//更新订单流水状态
				PaySerial selectPaySerial = new PaySerial();
				selectPaySerial.setPayOrderNo(payOrderNo);
				selectPaySerial.setPlatformId(platformId);
				PaySerial selectOne = paySerialBiz.selectOne(selectPaySerial);
				selectOne.setPayStatus("03");//支付中
				paySerialBiz.updateById(selectOne);
				selectPayOrder.setOrderStatus("03");//支付中
				payOrderBiz.updateById(selectPayOrder);
			}
			response.setPayObject((Map<String, Object>) retMap.get("payInfo"));
		}
		
		//临时测试用
//		Map<String, Object> map = new HashMap<>();
//		map.put("amount", String.valueOf(selectPayOrder.getPayAmt()));
//		map.put("orderNo", payOrderNo);
//		map.put("platformId", "14376521810391040");
//		map.put("tradeType", "1");
//		map.put("txStatus", "00");
//		String context = JSONUtils.toJSONString(map);
//		rabbitTemplate.convertAndSend("topic.payment", context);
		
		response.setCode((String) retMap.get("code"));
		response.setMsg((String) retMap.get("msg"));
		response.setSuccess((boolean) retMap.get("success"));
		return response;
	}


	/**
	 * 获取支付对象
	 * 限额控制--限额检查
	 * 同一收款订单 ：创建支付流水之前，修改其他支付中支付流水为失败
	 */
	private Map<String, Object> getPayObject(PayOrder payOrder, PayChannel payChannel, PaySerial paySerial, PayOrderRequest payOrderRequest) {

		logger.info("支付通道：{}", payChannel.getPayChannelNo());
		PayChannelInterface payChannelInterface = new PayChannelInterface();
		payChannelInterface.setPayChannelNo(payChannel.getPayChannelNo());
		payChannelInterface.setTradeType("00");//支付
		PayChannelInterface selectInterface = payChannelInterfaceMapper.selectOne(payChannelInterface);
		Map<String, Object> responseMap = new HashMap<String, Object>();
		if(selectInterface == null){
			logger.error("查询支付通道接口为null,支付通道编号:{}", payChannel.getPayChannelNo());
			responseMap.put("success", false);
			responseMap.put("code", ResponseCode.INTERFACE_NOTEXIST.getCode());
			responseMap.put("msg", ResponseCode.INTERFACE_NOTEXIST.getMessage());
			return responseMap;
		}

		logger.info("查询支付通道接口,支付接口:{}", selectInterface.getServiceName());

		if(!(SpringContextHolder.getBean(selectInterface.getServiceName()) instanceof PayObjectService)){
			logger.error("查询支付通道接口未实现PayObjectService,支付通道编号:{}",payChannel.getPayChannelNo());
			responseMap.put("success", false);
			responseMap.put("code", ResponseCode.PAYCHANNEL_INTERFACE_NOTEXIST.getCode());
			responseMap.put("msg", ResponseCode.PAYCHANNEL_INTERFACE_NOTEXIST.getMessage());
			return responseMap;
		}

		PayObjectService<OnlinePaymentRequest> payObjectService = SpringContextHolder.getBean(selectInterface.getServiceName());

		OnlinePaymentRequest request = new OnlinePaymentRequest();

		request.setMerchantId(payOrder.getMerchantId());
		request.setPayChannelNo(payChannel.getPayChannelNo());
		request.setPlatformId(payOrder.getPlatformId());
		request.setPayCompanyNo(payChannel.getPayCompanyNo());

		request.setSerialNo(paySerial.getSerialNo());
		request.setOrderAmt(payOrder.getPayAmt());
		request.setProductName(payOrder.getBody());
		request.setProductShortName(payOrder.getBody());
		request.setTxTime(payOrder.getPayTime());
		String custIp = "127.0.0.1";
		request.setExterInvokeIp(custIp);
		Map<String, Object> extra = new HashMap<String, Object>();
		String extValue = payOrderRequest.getExtValue();
		JSONObject extendMap = (JSONObject) JSONObject.parse(extValue);
		extra.put("openId", extendMap.get("openId"));
		request.setExtra(extra);
		return payObjectService.pay(request);
		
//		Map<String,Object> payInfoMap = new HashMap<String, Object>();
//		Map<String,Object> response = new HashMap<String, Object>();
//        payInfoMap.put("qr_code", "123456");
//        payInfoMap.put("code_url", "123456");
//        response.put("payInfo", payInfoMap);
//        response.put("success", true);
//        response.put("code", ResponseCode.OK.getCode());
//        response.put("msg", ResponseCode.OK.getMessage());
//        return response;

	}

	/**
	 * 拼装支付流水参数
	 * @return
	 */
	private PaySerial setPaySerial(PayOrderRequest request, PayOrder selectPayOrder){
		PaySerial paySerial = new PaySerial();
		paySerial.setPayOrderNo(request.getPayOrderNo());
		paySerial.setPlatformId(request.getPlatformId());
		paySerial.setMerchantId(selectPayOrder.getMerchantId());
		paySerial.setPayAmt(selectPayOrder.getPayAmt());
		paySerial.setPayFee(selectPayOrder.getPayFee());
		paySerial.setPayCompanyNo(request.getPayCompanyNo());
		paySerial.setPayChannelNo(request.getPayChannelNo());
		paySerial.setSerialNo(SequenceUtil.Create27DigitalOrAlphabet());
		paySerial.setPayStatus("02");//待支付
		return paySerial;
	}
	
}
